package it.okkam.utility;

import it.okkam.costants.CodiciComuni;
import it.okkam.costants.Costanti;
import it.okkam.strutturedati.ConfineComune;
import it.okkam.strutturedati.Extent;
import it.okkam.strutturedati.ExtentCcc;
import it.okkam.strutturedati.Punto;
import it.okkam.strutturedati.Vertice;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.vividsolutions.jts.geom.Coordinate;

public class UtilityQuery {
	
	/**
	 * trova l'indice in cui e' presente ^ e restituisce la sua posizione
	 * 
	 * @param Stringa  indagata
	 * @return intero con posizione punto
	 */
	
	public int trovaPosizioneCaret(String stringaIndagata) {
		int i = 0;
		for (int j = 0; j < stringaIndagata.length(); j++) {
			if (stringaIndagata.charAt(j) == '^') {
				i = j;}
		}
		return i-1;
	}
	
	
	
	/**
	 * restituisce la Stringa della coordinata partendo dal risultato della Query che e' del tipo 
	 * 11.1175^^http://www.w3.org/2001/XMLSchema#double 
	 * 
	 * @param Stringa  indagata
	 * @return intero con posizione punto
	 */
	
	public String getCoordinata(String stringaIndagata) {
		
		int indice = trovaPosizioneCaret(stringaIndagata);
		String coordinata = stringaIndagata.substring(0,indice);
		
		return coordinata;
	}

	/**
	 * restituisce la stringa di data e l'ora
	 * 
	 * @param 
	 * @return stringa 
	 */
	
	public String getData (){
		DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
		Date date = new Date();
		String out = "["+dateFormat.format(date)+"] ";
		return out;
	}
	
	/**
	 * Il metodo restituisce l'extent in ingresso in formato utile per fare la query
	 * 
	 * @param Extent 
	 * @return stringa 
	 */
	 public String getExtentStringFromExtent(Extent extent){
		 
		 String ext = new Double(extent.getxMin()).toString();
			ext = ext + " " + new Double(extent.getyMin()).toString();
			ext = ext + " " + new Double(extent.getxMax()).toString();
			ext = ext + " " + new Double(extent.getyMax()).toString();
		 return ext;
	 }
	 
		/**
		 * Il metodo restituisce l'extent in ingresso in formato utile per fare la query
		 * 
		 * @param HashMap<String,Extent> , String 
		 * @return stringa 
		 */
		 public String getExtentString(HashMap<String,Extent> extentsComuni,String key){
			 
			 String extent = new Double(extentsComuni.get(key).getxMin()).toString();
				extent = extent + " " + new Double(extentsComuni.get(key).getyMin()).toString();
				extent = extent + " " + new Double(extentsComuni.get(key).getxMax()).toString();
				extent = extent + " " + new Double(extentsComuni.get(key).getyMax()).toString();
			 return extent;
		 }
	 
	 /**
	 * Il metodo restituisce dal risultato della query sull ID solo l'ID
	 * 
	 * @param String 
	 * @return String 
	 */
	 public String getIDString(String idRaw){
			 
			 int index = idRaw.indexOf("\"");
			 String id = idRaw.substring(index+1);
			 index = id.indexOf("\"");
			 id = id.substring(0,index);

			 return id;
	 }
	 /**
	 * Il metodo restituisce l'extent in ingresso in formato utile per fare la query
	 * 
	 * @param HashMap<String,Extent> , String 
	 * @return String 
	 */
	 public Map<String, Set<String>> getSetOrderedByCambiamentoComuni(Map<String, Set<String>> mappaIn){
	     Map<String, Set<String>> cambiamentiComuni = new HashMap<String, Set<String>>();
	     
	     
	     Set keys = mappaIn.keySet(); // The set of keys in the map.
	     Iterator keyIter = keys.iterator();
	     
	     while (keyIter.hasNext()) {
	    	 String idComune = (String) keyIter.next(); // Get the next key.
	    	 getDataSet(idComune);
	    	 Set<String> listaCambiamenti = (Set) mappaIn.get(idComune); // Get the value for that key.
	    	 Iterator itr = listaCambiamenti.iterator();
	    	 
	    	 while(itr.hasNext()) {
	            String  idCambiamento = itr.next().toString();
	            Set<String> tmp = new HashSet<String>();
	            if(cambiamentiComuni.containsKey(idCambiamento)){
	            	tmp = cambiamentiComuni.get(idCambiamento);
	            	tmp.add(idComune);
	            	cambiamentiComuni.remove(idCambiamento);
	            	cambiamentiComuni.put(idCambiamento, tmp);
	            }
	            else{
	            	tmp.add(idComune);
	            	cambiamentiComuni.put(idCambiamento, tmp);
	            }
            }
	    	 
	     } 
		return cambiamentiComuni;	 
		 }

	 /**
		 * Il metodo restituisce la string del dataset del comune partendo dal codice del comune catastale
		 * 
		 * 
		 * @param String 
		 * @return String 
		 */

	public String getDataSet(String codiceComuneCatastale) {
		// TODO Auto-generated method stub
		CodiciComuni codice = new CodiciComuni();
		String dataSetComune = "http://www.okkam.it/ont/"; 
		Map<String, String> mappa = codice.ComuneMap2Code;
		Iterator k =  mappa.keySet().iterator();
		while (k.hasNext()){
			Object obj = k.next();
			String comune = (String) obj;
			String ccc = mappa.get(obj);
			if (ccc.equalsIgnoreCase(codiceComuneCatastale)){
				dataSetComune = dataSetComune + comune.toLowerCase();
				}
		}
		
		return dataSetComune;
	}






	 /**
	 * Il metodo restituisce la uri del comune.
	 * 
	 * @param  String codice del comune catastale
	 * @return String URI del comune
	 */


	public String getUriComune(String codiceComuneCatastale) {
		// TODO Auto-generated method stub
		CodiciComuni codice = new CodiciComuni();
		String comuneURI = "";
		Map<String, String> mappa = codice.ComuneMap2Code;
		Iterator k =  mappa.keySet().iterator();
		while (k.hasNext()){
			Object obj = k.next();
			String comune = (String) obj;
			String ccc = mappa.get(obj);
			if (ccc.equalsIgnoreCase(codiceComuneCatastale)){
				Costanti.setUriComuni();
				comuneURI = Costanti.uriComuni.get(comune);
				}
		}
		
		return comuneURI;
	
	}
	 /**
	 * Il metodo restituisce il percorso del file per la creazione del dataSet.
	 * 
	 * @param  String 
	 * @return String 
	 */


	public String getNameDataset(String comune) {
		// TODO Auto-generated method stub
		String out = "/home/okkam/Nicola/assemblers/"+comune.toLowerCase()+"-assembler.ttl";
		return out;
	}

	 /**
	 * Il metodo restituisce il nome del comune partendo dal codice comune catastale.
	 * 
	 * @param  String 
	 * @return String 
	 */


	public String getComune(String codiceComuneCatastale) {
		// TODO Auto-generated method stub
		CodiciComuni codice = new CodiciComuni();
		String comuneStringa = "";
		Map<String, String> mappa = codice.ComuneMap2Code;
		Iterator k =  mappa.keySet().iterator();
		while (k.hasNext()){
			Object obj = k.next();
			String comune = (String) obj;
			String ccc = mappa.get(obj);
			if (ccc.equalsIgnoreCase(codiceComuneCatastale)){
				comuneStringa = comune.toLowerCase();
				}
		}
		
		return comuneStringa;
	
	}



	public String getNomeGrafo(String comuneString) {
		// TODO Auto-generated method stub
		String out = "http://www.okkam.org/" + comuneString +"/particelle";
		//System.out.println("grafo: " + out);
		return out;
	}



	public String getGeometryExtentString(ExtentCcc extCcc) {
		// TODO Auto-generated method stub
		Extent ext = extCcc.getExt();
		String $1 = ext.xMin +" "+ ext.yMin +",";
		String $2 = ext.xMin +" "+ ext.yMax +",";
		String $3 = ext.xMax +" "+ ext.yMax +",";
		String $4 = ext.xMax +" "+ ext.yMin ;
		String geo = "LINESTRING ("+ $1 + " " + $2 + " " + $3 + " " + $4 + " )"; 
		return geo;
		
	}

	 /**
	 * Il metodo restituisce la stringa per la generzione della geometria partendo da una lista di punti/
	 * 
	 * @param  
	 * @return String List<Punto>
	 */	
	public String getStringGeometryCambiamento(List<Punto> punti) {
		// TODO Auto-generated method stub
		String geo = "LINESTRING (";
		Iterator<Punto> iter = punti.iterator();
		while (iter.hasNext()){
			Punto punto = iter.next();
			String vertice = Double.toString(punto.getX()) + " " + Double.toString(punto.getY()) + ", ";
			geo = geo + vertice; 	
		}
		int lenght = geo.length();
		geo = geo.substring(0, lenght-2);
		geo = geo + ")";
	//	System.out.println(geo);
		return geo;
	}

	 /**
	 * Il metodo restituisce la stringa per la generzione della geometria partendo da una lista di Vertice
	 * 
	 * @param  
	 * @return String List<Punto>
	 */	
	public String getStringGeometryPoligono(List<Vertice> v) {
		// TODO Auto-generated method stub
		String geo = "POLYGON ( (";
		Iterator<Vertice> iter = v.iterator();
		while (iter.hasNext()){
			Vertice vertice = iter.next();
			Punto punto = vertice.getVertice();
			String verticeString = Double.toString(punto.getX()) + " " + Double.toString(punto.getY()) + ", ";
			geo = geo + verticeString; 	
		}
		int lenght = geo.length();
		geo = geo.substring(0, lenght-2);
		geo = geo + ") )";
		return geo;
	}
	
	 /**
	 * DA COMMENTARE (SE FUNZIONA)
	 * 
	 * @param  
	 * @return String List<Punto>
	 */	
	public Coordinate[] getListCoordVertici(List<Vertice> v) {
		// TODO Auto-generated method stub
		int size = v.size()+1;
		int i = 0;
		Coordinate[] lista = new Coordinate[size];
		Iterator<Vertice> iter = v.iterator();
		while (iter.hasNext()){
			Vertice vertice = iter.next();
			Punto punto = vertice.getVertice();
			Coordinate c = new Coordinate(punto.getX() , punto.getY());
			lista[i]= c ;
			i++;
		}
		lista[size-1] = lista[0];

		return lista ;
	}
	
	 /**
	 * DA COMMENTARE (SE FUNZIONA)
	 * 
	 * @param  
	 * @return String List<Punto>
	 */	
	public Coordinate[] getListCoordPunto(List<Punto> p) {
		// TODO Auto-generated method stub
		int size = p.size()+1;
		int i = 0;
		Coordinate[] lista = new Coordinate[size];
		Iterator<Punto> iter = p.iterator();
		while (iter.hasNext()){
			Punto punto = iter.next();
			Coordinate c = new Coordinate(punto.getX() , punto.getY());
			lista[i]= c ;
			i++;
		}
		lista[size-1] = lista[0];
		return lista ;
	}
		

}
			 


